import 'dart:async';
import 'dart:convert';
import '../models/notification_message.dart';
import '../utils/storage_util.dart';
import 'notification_api_service.dart';

/// 离线消息服务 - 管理离线期间收到的消息
class OfflineMessageService {
  static final OfflineMessageService _instance = OfflineMessageService._internal();
  factory OfflineMessageService() => _instance;
  OfflineMessageService._internal();

  final NotificationApiService _apiService = NotificationApiService();
  
  static const String _offlineMessagesKey = 'offline_messages';
  static const String _lastOnlineTimeKey = 'last_online_time';
  static const String _unreadCountKey = 'unread_count';
  static const String _lastSyncTimeKey = 'last_sync_time';

  // 消息流控制器
  final StreamController<List<NotificationMessage>> _messagesController = 
      StreamController<List<NotificationMessage>>.broadcast();
  
  final StreamController<int> _unreadCountController = 
      StreamController<int>.broadcast();

  /// 消息列表流
  Stream<List<NotificationMessage>> get messagesStream => _messagesController.stream;
  
  /// 未读消息数量流
  Stream<int> get unreadCountStream => _unreadCountController.stream;

  /// 保存离线消息
  Future<void> saveOfflineMessage(NotificationMessage message) async {
    try {
      final messages = await getOfflineMessages();
      
      // 标记为离线消息
      final offlineMessage = message.copyWith(isOffline: true);
      messages.add(offlineMessage);
      
      // 保存到本地存储
      await _saveMessagesToStorage(messages);
      
      // 更新未读数量
      await _updateUnreadCount();
      
      // 通知监听者
      _messagesController.add(messages);
      
    } catch (e) {
    }
  }

  /// 批量保存离线消息
  Future<void> saveOfflineMessages(List<NotificationMessage> newMessages) async {
    try {
      final existingMessages = await getOfflineMessages();
      
      // 标记为离线消息并去重
      final offlineMessages = newMessages.map((msg) => msg.copyWith(isOffline: true)).toList();
      
      // 合并消息，避免重复
      final allMessages = [...existingMessages];
      for (final newMsg in offlineMessages) {
        if (!allMessages.any((existing) => existing.id == newMsg.id)) {
          allMessages.add(newMsg);
        }
      }
      
      // 按时间排序（最新的在前）
      allMessages.sort((a, b) => b.timestamp.compareTo(a.timestamp));
      
      await _saveMessagesToStorage(allMessages);
      await _updateUnreadCount();
      
      _messagesController.add(allMessages);
      
    } catch (e) {
    }
  }

  /// 获取所有离线消息（优先从Redis获取，本地作为缓存）
  Future<List<NotificationMessage>> getOfflineMessages() async {
    try {
      // 首先尝试从Redis获取最新消息
      final result = await _apiService.getMessages();
      if (result['success'] == true) {
        final List<NotificationMessage> redisMessages = result['data'] ?? [];
        
        // 更新本地缓存
        await _saveMessagesToStorage(redisMessages);
        
        return redisMessages;
      } else {
        
        // Redis获取失败，使用本地缓存
        return await _getLocalMessages();
      }
    } catch (e) {
      return await _getLocalMessages();
    }
  }

  /// 从本地缓存获取消息
  Future<List<NotificationMessage>> _getLocalMessages() async {
    try {
      final messagesJson = await StorageUtil.getValue(_offlineMessagesKey);
      if (messagesJson == null || messagesJson.isEmpty) {
        return [];
      }
      
      final List<dynamic> messagesList = jsonDecode(messagesJson);
      return messagesList.map((json) => NotificationMessage.fromJson(json)).toList();
    } catch (e) {
      return [];
    }
  }

  /// 获取未读消息数量（优先从Redis获取）
  Future<int> getUnreadCount() async {
    try {
      // 首先尝试从Redis获取
      final result = await _apiService.getUnreadCount();
      if (result['success'] == true) {
        final count = result['data'] ?? 0;
        
        // 更新本地缓存
        await StorageUtil.setValue(_unreadCountKey, count.toString());
        
        return count;
      } else {
        
        // Redis获取失败，使用本地缓存
        final countStr = await StorageUtil.getValue(_unreadCountKey);
        return int.tryParse(countStr ?? '0') ?? 0;
      }
    } catch (e) {
      final countStr = await StorageUtil.getValue(_unreadCountKey);
      return int.tryParse(countStr ?? '0') ?? 0;
    }
  }

  /// 标记消息为已读（同步到Redis）
  Future<void> markMessageAsRead(String messageId) async {
    try {
      // 从extraData中获取index
      final messages = await _getLocalMessages();
      NotificationMessage? targetMessage;
      int? messageIndex;
      
      for (final message in messages) {
        if (message.id == messageId) {
          targetMessage = message;
          messageIndex = message.extraData?['index'] as int?;
          break;
        }
      }
      
      if (targetMessage != null && messageIndex != null) {
        // 调用API标记为已读
        final result = await _apiService.markAsRead(messageId, messageIndex);
        
        if (result['success'] == true) {
          // API调用成功，更新本地缓存
          final updatedMessages = messages.map((msg) {
            if (msg.id == messageId) {
              return msg.copyWith(isRead: true);
            }
            return msg;
          }).toList();
          
          await _saveMessagesToStorage(updatedMessages);
          await _updateUnreadCount();
          _messagesController.add(updatedMessages);
          
        } else {
          throw Exception(result['message']);
        }
      } else {
        throw Exception('消息不存在或缺少索引信息');
      }
    } catch (e) {
      rethrow;
    }
  }

  /// 标记所有消息为已读（同步到Redis）
  Future<void> markAllMessagesAsRead() async {
    try {
      // 调用API标记所有消息为已读
      final result = await _apiService.markAllAsRead();
      
      if (result['success'] == true) {
        // API调用成功，更新本地缓存
        final messages = await _getLocalMessages();
        final updatedMessages = messages.map((msg) => msg.copyWith(isRead: true)).toList();
        
        await _saveMessagesToStorage(updatedMessages);
        await _updateUnreadCount();
        _messagesController.add(updatedMessages);
        
      } else {
        throw Exception(result['message']);
      }
    } catch (e) {
      rethrow;
    }
  }

  /// 删除消息（同步到Redis）
  Future<void> deleteMessage(String messageId) async {
    try {
      // 从extraData中获取index
      final messages = await _getLocalMessages();
      NotificationMessage? targetMessage;
      int? messageIndex;
      
      for (final message in messages) {
        if (message.id == messageId) {
          targetMessage = message;
          messageIndex = message.extraData?['index'] as int?;
          break;
        }
      }
      
      if (targetMessage != null && messageIndex != null) {
        // 调用API删除消息
        final result = await _apiService.deleteMessage(messageIndex);
        
        if (result['success'] == true) {
          // API调用成功，更新本地缓存
          final updatedMessages = messages.where((msg) => msg.id != messageId).toList();
          
          await _saveMessagesToStorage(updatedMessages);
          await _updateUnreadCount();
          _messagesController.add(updatedMessages);
          
        } else {
          throw Exception(result['message']);
        }
      } else {
        throw Exception('消息不存在或缺少索引信息');
      }
    } catch (e) {
      rethrow;
    }
  }

  /// 清空所有消息（同步到Redis）
  Future<void> clearAllMessages() async {
    try {
      // 调用API清空所有消息
      final result = await _apiService.clearAllMessages();
      
      if (result['success'] == true) {
        // API调用成功，清空本地缓存
        await StorageUtil.removeValue(_offlineMessagesKey);
        await StorageUtil.removeValue(_unreadCountKey);
        
        _messagesController.add([]);
        _unreadCountController.add(0);
        
      } else {
        throw Exception(result['message']);
      }
    } catch (e) {
      rethrow;
    }
  }

  /// 记录用户上线时间
  Future<void> recordOnlineTime() async {
    try {
      final now = DateTime.now().millisecondsSinceEpoch.toString();
      await StorageUtil.setValue(_lastOnlineTimeKey, now);
    } catch (e) {
    }
  }

  /// 获取上次上线时间
  Future<DateTime?> getLastOnlineTime() async {
    try {
      final timeStr = await StorageUtil.getValue(_lastOnlineTimeKey);
      if (timeStr != null) {
        final timestamp = int.tryParse(timeStr);
        if (timestamp != null) {
          return DateTime.fromMillisecondsSinceEpoch(timestamp);
        }
      }
      return null;
    } catch (e) {
      return null;
    }
  }

  /// 发送通知消息到Redis
  Future<void> sendNotificationToRedis({
    required String toUserId,
    required String notificationType,
    required String title,
    required String content,
    String? senderName,
    String? senderId,
    String? targetId,
    String? targetType,
    String? navigationPath,
    Map<String, dynamic>? navigationParams,
  }) async {
    try {
      final result = await _apiService.sendNotification(
        toUserId: toUserId,
        notificationType: notificationType,
        title: title,
        content: content,
        senderName: senderName,
        senderId: senderId,
        targetId: targetId,
        targetType: targetType,
        navigationPath: navigationPath,
        navigationParams: navigationParams,
      );
      
      if (result['success'] == true) {
      } else {
        throw Exception(result['message']);
      }
    } catch (e) {
      rethrow;
    }
  }

  /// 同步离线消息（用户重新上线时调用）
  Future<void> syncOfflineMessages() async {
    try {
      
      // 直接从Redis获取所有消息（包括离线期间的消息）
      final result = await _apiService.getMessages();
      
      if (result['success'] == true) {
        final List<NotificationMessage> redisMessages = result['data'] ?? [];
        
        // 更新本地缓存
        await _saveMessagesToStorage(redisMessages);
        
        // 通知UI更新
        _messagesController.add(redisMessages);
        
        // 更新未读数量
        await _updateUnreadCount();
        
      } else {
      }
      
      // 更新同步时间
      await _recordSyncTime();
      
    } catch (e) {
    }
  }

  /// 记录同步时间
  Future<void> _recordSyncTime() async {
    try {
      final now = DateTime.now().millisecondsSinceEpoch.toString();
      await StorageUtil.setValue(_lastSyncTimeKey, now);
    } catch (e) {
    }
  }

  /// 保存消息到本地存储
  Future<void> _saveMessagesToStorage(List<NotificationMessage> messages) async {
    final messagesJson = jsonEncode(messages.map((msg) => msg.toJson()).toList());
    await StorageUtil.setValue(_offlineMessagesKey, messagesJson);
  }

  /// 更新未读数量
  Future<void> _updateUnreadCount() async {
    final messages = await getOfflineMessages();
    final unreadCount = messages.where((msg) => !msg.isRead).length;
    
    await StorageUtil.setValue(_unreadCountKey, unreadCount.toString());
    _unreadCountController.add(unreadCount);
  }

  /// 初始化服务（应用启动时调用）
  Future<void> initialize() async {
    try {
      // 加载现有消息
      final messages = await getOfflineMessages();
      _messagesController.add(messages);
      
      // 更新未读数量
      await _updateUnreadCount();
      
    } catch (e) {
    }
  }

  /// 释放资源
  void dispose() {
    _messagesController.close();
    _unreadCountController.close();
  }
}